package Equipment;

import java.net.HttpURLConnection;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.Random;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.ws.BindingProvider;

import org.jboss.ws.core.StubExt;

import edu.ipfw.fitness.EquipmentCategoryType;
import edu.ipfw.fitness.EquipmentIdListType;
import edu.ipfw.fitness.EquipmentUsageListType;
import edu.ipfw.services.equipment.Equipment;
import edu.ipfw.services.equipment.EquipmentService;
import edu.ipfw.services.equipment.SecureEquipment;
import edu.ipfw.services.equipment.SecureEquipmentService;

public class SecureEquipmentClient {
	//	1.	Add a Java application class named SecureEquipmentClient to your cs590-project2-test project.
	//	2.	Construct SecureEquipment service calls to accomplish the following:
	//		a.	Configure the RequestContext with a username of ‘admin’ and a password of ‘ubertusker’.
	//		b.	Add a TM Equipment with id of TM-01, description of “Precor”.
	//		c.	Add a TM Equipment with id of TM-02, description of “Life Fitness with heart monitor”.
	//		d.	Add a EL Equipment with id of EL-01, description of “EFX Cross Trainer”.
	//		e.	Add a EL Equipment with id of EL-02, description of “EFX Cross Trainer”.
	//		f.	Record three usage entries for each Equipment with different, but overlapping, date/time ranges. Make one of the start date/times for each Equipment correspond to the current system time. Vary the duration of the end date/times from 20 minutes to 90 minutes and the miles from 1.0 to 13.1. 
	//		g.	Record maintenance of TM-01 using current system date.
	//		h.	Remove EL-01.
	//	3.	Construct Equipment service calls to accomplish the following:
	//		a.	Configure the RequestContext with a username of ‘admin’ and a password of ‘ubertusker’.
	//		b.	Display all Equipment (getEquipmentList).
	//		c.	Display usage for TM-01.
	//		d.	Display usage for TM-01 between the earliest start date and latest end date you used when recording usage entries. (getUsageForDates)
	//		e.	Display ids of Equipment needing maintenance (should be empty).
	//	4.	Configure the Equipment RequestContext with a username of ‘staff1’ and a password of ‘tusker1’.
	//	5.	Repeat steps 3b-3e.
	//	6.	Configure the SecureEquipment RequestContext with a username of ‘staff1’ and a password of ‘tusker1’.
	//	7.	Attempt to add a TM Equipment with id of TM-03, description of “Precor”.
	//	8.	Configure the Equipment RequestContext with a username of ‘hacker’ and a password of ‘nogood’.
	//	9.	Attempt to display all Equipment (getEquipmentList).
	//	10.	Configure the SecureEquipment RequestContext with a username of ‘hacker’ and a password of ‘nogood’.
	//	11.	Attempt to add a TM Equipment with id of TM-03, description of “Precor”.
	public static void main(String[] args) 
	{
		//2.	Construct SecureEquipment service calls to accomplish the following:
		SecureEquipment se = new SecureEquipment();
		SecureEquipmentService seService = se.getSecureEquipmentServiceImplPort();
		
		System.out.println("***************START OF FIRST SECURE EQUIPMENT TEST***************");
		
		Map<String,Object> requestContext = ((BindingProvider) seService).getRequestContext();
		
		//2.a.	Configure the RequestContext with a username of ‘admin’ and a password of ‘ubertusker’.
		System.out.println("UserID=admin and Password=ubertusker");
		String userid = "admin";
		String password = "ubertusker";
		
		requestContext.put(BindingProvider.USERNAME_PROPERTY, userid);
		requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
		
		((StubExt) seService).setConfigName("Standard WSSecurity Client");
		try {
			System.out.println();
			
			//2.b. Add a TM Equipment with id of TM-01, description of “Precor”.
			System.out.println("Test 2.b: Add a TM Equipment with id of TM-01, description of “Precor”.");
			seService.add("TM-01", EquipmentCategoryType.TM, "Precor");
			
			System.out.println();
			
			//2.c.	Add a TM Equipment with id of TM-02, description of “Life Fitness with heart monitor”.
			System.out.println("Test 2.c: Add a TM Equipment with id of TM-02, description of “Life Fitness with heart monitor”.");
			seService.add("TM-02", EquipmentCategoryType.TM, "Life Fitness with heart monitor");
			
			System.out.println();
			
			//2.d.	Add a EL Equipment with id of EL-01, description of “EFX Cross Trainer”.
			System.out.println("Test 2.d: Add a EL Equipment with id of EL-01, description of “EFX Cross Trainer”.");
			seService.add("EL-01", EquipmentCategoryType.EL, "EFX Cross Trainer");
			
			System.out.println();
			
			//2.e.	Add a EL Equipment with id of EL-02, description of “EFX Cross Trainer”.
			System.out.println("Test 2.e: Add a EL Equipment with id of EL-02, description of “EFX Cross Trainer”.");
			seService.add("EL-02", EquipmentCategoryType.EL, "EFX Cross Trainer");
			
			System.out.println();
			
			//2.f.	Record three usage entries for each Equipment with different, but overlapping, 
			//		date/time ranges. Make one of the start date/times for each Equipment correspond to 
			//		the current system time. Vary the duration of the end date/times from 20 minutes to 
			//		90 minutes and the miles from 1.0 to 13.1.
			System.out.println("Test 2.f: Record three usage entries for each piece of Equipment entered above.");
			seService.recordUsage("TM-01", getCurrentDateTime(), getEndDateTime(),
					new Float("6.6"));
			seService.recordUsage("TM-01", getCurrentDateTime(), getEndDateTime(),
					new Float("10.4"));
			seService.recordUsage("TM-01", getCurrentDateTime(), getEndDateTime(),
					new Float("2.1"));
			
			seService.recordUsage("TM-02", getCurrentDateTime(), getEndDateTime(),
					new Float("3.8"));
			seService.recordUsage("TM-02", getCurrentDateTime(), getEndDateTime(),
					new Float("10.9"));
			seService.recordUsage("TM-02", getCurrentDateTime(), getEndDateTime(),
					new Float("7.3"));
			
			seService.recordUsage("EL-01", getCurrentDateTime(), getEndDateTime(),
					new Float("4.8"));
			seService.recordUsage("EL-01", getCurrentDateTime(), getEndDateTime(),
					new Float("11.9"));
			seService.recordUsage("EL-01", getCurrentDateTime(), getEndDateTime(),
					new Float("5.3"));
			
			seService.recordUsage("EL-02", getCurrentDateTime(), getEndDateTime(),
					new Float("9.8"));
			seService.recordUsage("EL-02", getCurrentDateTime(), getEndDateTime(),
					new Float("9.9"));
			seService.recordUsage("EL-02", getCurrentDateTime(), getEndDateTime(),
					new Float("8.3"));
			
			System.out.println();
			
			//2.g.	Record maintenance of TM-01 using current system date.
			System.out.println("Test 2.g: Record maintenance of TM-01 using current system date.");
			seService.maintain("TM-01");
			
			System.out.println();
			
			//2.h.	Remove EL-01.
			System.out.println("Test 2.h: Remove EL-01.");
			seService.remove("EL-01");
			
		} catch (Exception e) {
		        String message = e.getMessage();
		        e.printStackTrace();
		        System.out.println(message);
		        if (message.contains(""+HttpURLConnection.HTTP_UNAUTHORIZED))
		        	System.out.println("User failed authentication.");
		        else
		        	System.out.println("User failed authorization.");
		}
		
		System.out.println();
		System.out.println("***************END OF FIRST SECURE EQUIPMENT TEST***************");
		System.out.println();
		System.out.println();
		
		//3.	Construct Equipment service calls to accomplish the following:
		Equipment e = new Equipment();
		EquipmentService eService = e.getEquipmentServiceImplPort();
		
		System.out.println("***************START OF FIRST EQUIPMENT TEST***************");
		
		requestContext = ((BindingProvider) eService).getRequestContext();
		
		//3.a.	Configure the RequestContext with a username of ‘admin’ and a password of ‘ubertusker’.
		System.out.println("UserID=admin and Password=ubertusker");
		userid = "admin";
		password = "ubertusker";
		
		System.out.println();
		
		requestContext.put(BindingProvider.USERNAME_PROPERTY, userid);
		requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
		
		try {
			//3.b.	Display all Equipment (getEquipmentList).
			// Display current equipment list
			System.out.println("Test 3.b: Displaying Equipment List:");
			EquipmentIdListType qTest = eService.getEquipmentList(null);
			for (int i = 0; i < qTest.getId().size(); i++) {
				System.out.println("\t" + qTest.getId().get(i).toString());
			}
			
			// Line spacer
			System.out.println("");
			
			//3.c.	Display usage for TM-01.
			EquipmentUsageListType k = eService.getUsage("TM-01");

			System.out.println("Test 3.c: Display usage for TM-01");

			for (int i = 0; i < k.getUsageEntry().size(); i++) {
				System.out.println("\tStart Time: "
						+ k.getUsageEntry().get(i).getStartTime());
				System.out.println("\tStop Time: "
						+ k.getUsageEntry().get(i).getStopTime());
			}
			
			System.out.println();
			
			//3.d.	Display usage for TM-01 between the earliest start date and latest 
			//		end date you used when recording usage entries. (getUsageForDates)
			
			// Create startDateTime to pass in
			GregorianCalendar gcStart = (GregorianCalendar) new GregorianCalendar().getInstance();
			// Subtract 90 minutes from current time to use as start time
			gcStart.add(Calendar.MINUTE, (-90));
			XMLGregorianCalendar startDTF = null;
			try {
				startDTF = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcStart);
			} catch (DatatypeConfigurationException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			// Create stopDateTime to pass in
			GregorianCalendar gcEnd = (GregorianCalendar) new GregorianCalendar()
					.getInstance();
			// Add 90 minutes from current time to use as end time
			gcEnd.add(Calendar.MINUTE, (+90));
			XMLGregorianCalendar endDTF = null;
			try {
				endDTF = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcEnd);
			} catch (DatatypeConfigurationException exp) {
				// TODO Auto-generated catch block
				exp.printStackTrace();
			}
			
			// Get the usage list
			EquipmentUsageListType m = eService.getUsageForDataRange(startDTF, endDTF, "TM-01");

			System.out.println("Test 3.d: Display usage for TM-01 between earliest start date and latest end date");
			
			//System.out.println("SIZE: " + m.getUsageEntry().size());
			for (int i = 0; i < m.getUsageEntry().size(); i++) {
				System.out.println("\tStart Time: "
						+ m.getUsageEntry().get(i).getStartTime());
				System.out.println("\tStop Time: "
						+ m.getUsageEntry().get(i).getStopTime());
			}
			
			System.out.println();
			
			// 3.e. Display ids of Equipment needing maintenance (should be empty).
			EquipmentIdListType o = eService.getMaintenanceDue();

			System.out.println("Test 3.e: Display ids of Equipment needing maintenance (should be empty).");

			System.out.println("\tList of equipment ids needing maintenance:");

			for (int i = 0; i < o.getId().size(); i++) {
				System.out.println("\tEquipment Requires Maintenance: "
						+ o.getId().get(i).toString());
			}
			
		} catch (Exception exp) {
		        String message = exp.getMessage();
		        //e.printStackTrace();
		        System.out.println(message);
		        if (message.contains(""+HttpURLConnection.HTTP_UNAUTHORIZED))
		        	System.out.println("User failed authentication.");
		        else
		        	System.out.println("User failed authorization.");
		}
		
		System.out.println();
		System.out.println("***************END OF FIRST EQUIPMENT TEST***************");
		System.out.println();
		System.out.println();
		
		
		//3.	Construct Equipment service calls to accomplish the following:
		System.out.println("***************START OF SECOND EQUIPMENT TEST***************");
		
		requestContext = ((BindingProvider) eService).getRequestContext();
		
		//4.	Configure the Equipment RequestContext with a username of ‘staff1’ and a password of ‘tusker1’.
		System.out.println("UserID=staff1 and Password=tusker1");
		userid = "staff1";
		password = "tusker1";
		
		System.out.println();
		
		requestContext.put(BindingProvider.USERNAME_PROPERTY, userid);
		requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
		
		try {
			//4.b.	Display all Equipment (getEquipmentList).
			// Display current equipment list
			System.out.println("Test 4.b: Displaying Equipment List:");
			EquipmentIdListType qTest = eService.getEquipmentList(null);
			for (int i = 0; i < qTest.getId().size(); i++) {
				System.out.println("\t" + qTest.getId().get(i).toString());
			}
			
			// Line spacer
			System.out.println("");
			
			//4.c.	Display usage for TM-01.
			EquipmentUsageListType k = eService.getUsage("TM-01");

			System.out.println("Test 4.c: Display usage for TM-01");

			for (int i = 0; i < k.getUsageEntry().size(); i++) {
				System.out.println("\tStart Time: "
						+ k.getUsageEntry().get(i).getStartTime());
				System.out.println("\tStop Time: "
						+ k.getUsageEntry().get(i).getStopTime());
			}
			
			System.out.println();
			
			//4.d.	Display usage for TM-01 between the earliest start date and latest 
			//		end date you used when recording usage entries. (getUsageForDates)
			
			// Create startDateTime to pass in
			GregorianCalendar gcStart = (GregorianCalendar) new GregorianCalendar().getInstance();
			// Subtract 90 minutes from current time to use as start time
			gcStart.add(Calendar.MINUTE, (-90));
			XMLGregorianCalendar startDTF = null;
			try {
				startDTF = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcStart);
			} catch (DatatypeConfigurationException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			// Create stopDateTime to pass in
			GregorianCalendar gcEnd = (GregorianCalendar) new GregorianCalendar()
					.getInstance();
			// Add 90 minutes from current time to use as end time
			gcEnd.add(Calendar.MINUTE, (+90));
			XMLGregorianCalendar endDTF = null;
			try {
				endDTF = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcEnd);
			} catch (DatatypeConfigurationException exp) {
				// TODO Auto-generated catch block
				exp.printStackTrace();
			}
			
			// Get the usage list
			EquipmentUsageListType m = eService.getUsageForDataRange(startDTF, endDTF, "TM-01");

			System.out.println("Test 3.d: Display usage for TM-01 between earliest start date and latest end date");
			
			//System.out.println("SIZE: " + m.getUsageEntry().size());
			for (int i = 0; i < m.getUsageEntry().size(); i++) {
				System.out.println("\tStart Time: "
						+ m.getUsageEntry().get(i).getStartTime());
				System.out.println("\tStop Time: "
						+ m.getUsageEntry().get(i).getStopTime());
			}
			
			System.out.println();
			
			// 4.e. Display ids of Equipment needing maintenance (should be empty).
			EquipmentIdListType o = eService.getMaintenanceDue();

			System.out.println("Test 4.e: Display ids of Equipment needing maintenance (should be empty).");

			System.out.println("\tList of equipment ids needing maintenance:");

			for (int i = 0; i < o.getId().size(); i++) {
				System.out.println("\tEquipment Requires Maintenance: "
						+ o.getId().get(i).toString());
			}
			
		} catch (Exception exp) {
		        String message = exp.getMessage();
		        //e.printStackTrace();
		        System.out.println(message);
		        if (message.contains(""+HttpURLConnection.HTTP_UNAUTHORIZED))
		        	System.out.println("User failed authentication.");
		        else
		        	System.out.println("User failed authorization.");
		}
		
		System.out.println();
		System.out.println("***************END OF SECOND EQUIPMENT TEST***************");
		System.out.println();
		System.out.println();
		
		
		System.out.println("***************START OF SECOND SECURE EQUIPMENT TEST***************");
		
		requestContext = ((BindingProvider) seService).getRequestContext();
		
		//6.	Configure the SecureEquipment RequestContext with a username of ‘staff1’ and a password of ‘tusker1’.
		System.out.println("UserID=staff1 and Password=tusker1");
		userid = "staff1";
		password = "tusker1";
		
		requestContext.put(BindingProvider.USERNAME_PROPERTY, userid);
		requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
		
		//((StubExt) seService).setConfigName("Standard WSSecurity Client");
		try {
			System.out.println();
			
			//7.	Attempt to add a TM Equipment with id of TM-03, description of “Precor”.
			System.out.println("Test 7: Attempt to add a TM Equipment with id of TM-03, description of “Precor”.");
			seService.add("TM-03", EquipmentCategoryType.TM, "Precor");
			
		} catch (Exception exp) {
		        String message = exp.getMessage();
		        //exp.printStackTrace();
		        System.out.println(message);
		        if (message.contains(""+HttpURLConnection.HTTP_UNAUTHORIZED))
		        	System.out.println("User failed authentication.");
		        else
		        	System.out.println("User failed authorization.");
		}
		
		System.out.println();
		System.out.println("***************END OF SECOND SECURE EQUIPMENT TEST***************");
		System.out.println();
		System.out.println();
		
		
		System.out.println("***************START OF THIRD EQUIPMENT TEST***************");
		
		requestContext = ((BindingProvider) eService).getRequestContext();
		
		//8.	Configure the Equipment RequestContext with a username of ‘hacker’ and a password of ‘nogood’.
		System.out.println("UserID=hacker and Password=nogood");
		userid = "hacker";
		password = "nogood";
		
		requestContext.put(BindingProvider.USERNAME_PROPERTY, userid);
		requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
		
		//((StubExt) seService).setConfigName("Standard WSSecurity Client");
		try {
			System.out.println();
			
			//9.	Attempt to display all Equipment (getEquipmentList).
			System.out.println("Test 9: Attempt to display all Equipment (getEquipmentList).");
			// Display current equipment list
			EquipmentIdListType qTest = eService.getEquipmentList(null);
			for (int i = 0; i < qTest.getId().size(); i++) {
				System.out.println("\t" + qTest.getId().get(i).toString());
			}
			
		} catch (Exception exp) {
		        String message = exp.getMessage();
		        //exp.printStackTrace();
		        System.out.println(message);
		        if (message.contains(""+HttpURLConnection.HTTP_UNAUTHORIZED))
		        	System.out.println("User failed authentication.");
		        else
		        	System.out.println("User failed authorization.");
		}
		
		System.out.println();
		System.out.println("***************END OF THIRD EQUIPMENT TEST***************");
		System.out.println();
		System.out.println();
		
		
		System.out.println("***************START OF THIRD SECURE EQUIPMENT TEST***************");
		
		requestContext = ((BindingProvider) seService).getRequestContext();
		
		//10.	Configure the SecureEquipment RequestContext with a username of ‘hacker’ and a password of ‘nogood’.
		System.out.println("UserID=hacker and Password=nogood");
		userid = "hacker";
		password = "nogood";
		
		requestContext.put(BindingProvider.USERNAME_PROPERTY, userid);
		requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
		
		//((StubExt) seService).setConfigName("Standard WSSecurity Client");
		try {
			System.out.println();
			
			//11.	Attempt to add a TM Equipment with id of TM-03, description of “Precor”.
			System.out.println("Test 11: Attempt to add a TM Equipment with id of TM-03, description of “Precor”.");
			seService.add("TM-03", EquipmentCategoryType.TM, "Precor");
			
		} catch (Exception exp) {
		        String message = exp.getMessage();
		        //exp.printStackTrace();
		        System.out.println(message);
		        if (message.contains(""+HttpURLConnection.HTTP_UNAUTHORIZED))
		        	System.out.println("User failed authentication.");
		        else
		        	System.out.println("User failed authorization.");
		}
		
		System.out.println();
		System.out.println("***************END OF THIRD SECURE EQUIPMENT TEST***************");
		System.out.println();
		System.out.println();
	}
	
	
	
	
	
	// Get current date and time
	private static XMLGregorianCalendar getCurrentDateTime()
			throws DatatypeConfigurationException {
		GregorianCalendar gc = (GregorianCalendar) new GregorianCalendar()
				.getInstance();
		XMLGregorianCalendar dtf = null;
		dtf = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
		//System.out.println("getCurrentDateTime() = " + dtf.toString());
		return dtf;
	}

	// Generate end time, base on current time plus 20 to 90 minutes
	private static XMLGregorianCalendar getEndDateTime()
			throws DatatypeConfigurationException {
		Random r = new Random(); // Default seed comes from system time.
		GregorianCalendar gc = (GregorianCalendar) new GregorianCalendar()
				.getInstance();
		// Generate random minutes to add between 20 and 90.
		gc.add(Calendar.MINUTE, (r.nextInt(70) + 20));
		XMLGregorianCalendar dtf = null;
		dtf = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
		//System.out.println("getEndDateTime() = " + dtf.toString());
		return dtf;
	}
}
